其他
ggplot2绘图进阶:如何在不同分面添加不同图形
1引言
有时候我们可能想在不同不同的分面添加不同的内容,比如文字,图形等等,今天分享一下如何在不同分面添加对应的图形进去。
参考链接:
一个兄弟的在线笔记,我们来学习一下:
https://clarewest.github.io/blog-posts/ggplotInset.html
2绘图
整理数据:
library(ggplot2) ## for plotting
library(dplyr) ## for data manipulation
library(lubridate) ## for handling dates
nobel <- read.csv("https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2019/2019-05-14/nobel_winners.csv")
plot_data <-
nobel %>%
mutate(prize_date = paste0(prize_year, "-12-10"),
age = time_length(interval(ymd(birth_date), ymd(prize_date)), "year")) %>%
group_by(prize_year, laureate_id) %>%
slice(1) %>% ## make sure we have just one row per prizewinner per year
ungroup()
分面绘图:
main_plot <-
ggplot(plot_data, aes(group=category)) +
geom_point(aes(x=prize_year, y=age, colour=gender), alpha=0.6) +
facet_wrap(~category) + ## plot each prize category separately
theme_bw() +
labs(y="Age of prize winner", x="Year of award") +
geom_smooth(aes(x=prize_year, y=age), method = "loess") + ## add a smoothed line
scale_y_continuous(limits=c(0,100)) +
scale_colour_discrete(breaks=c("Female","Male")) +
theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
legend.position = "bottom",
legend.title = element_blank())
main_plot
绘制插入的图形:
## A function to plot the inset
get_inset <- function(df){
p <- ggplot(data=df %>%
group_by(category, prize_year) %>%
slice(1),
aes(x=prize_share, fill=category)) +
geom_bar() +
scale_x_discrete( drop=FALSE) +
scale_fill_manual(values = c("#00BF7D", "#A3A500", "#F8766D","#00B0F6","#E76BF3","#636363")) +
guides(fill=FALSE) +
theme_bw(base_size=9) + ## makes everything smaller
theme(panel.background = element_rect(fill="white"), ## white plot background
axis.title.y = element_blank(),
axis.title.x = element_blank(),
axis.text.x = element_text(size=rel(0.7)), ## tiny axis text
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
plot.background = element_blank())
return(p)
}
inset_plot <- get_inset(plot_data)
inset_plot
给分面插入图形:
## Add it as an inset
main_plot +
annotation_custom(grob=ggplotGrob(inset_plot),
ymin = -8, ymax=34, xmin=1955, xmax=2015)
可以看到每个分面插入了一模一样的图形,并不是我们想要的结果。
重新定义 annotation_custom 函数:
## This function allows us to specify which facet to annotate
annotation_custom2 <- function (grob, xmin = -Inf, xmax = Inf, ymin = -Inf, ymax = Inf, data)
{
layer(data = data, stat = StatIdentity, position = PositionIdentity,
geom = ggplot2:::GeomCustomAnn,
inherit.aes = TRUE, params = list(grob = grob,
xmin = xmin, xmax = xmax,
ymin = ymin, ymax = ymax))
}
指定特定的分面进行插入:
main_plot +
annotation_custom2(grob=ggplotGrob(inset_plot),
data = data.frame(category="Chemistry"),
ymin = -8, ymax=34, xmin=1955, xmax=2015)
这里关键的代码是 **data = data.frame(category="Chemistry")**。
批量插入:
library(purrr)
insets <- plot_data %>%
split(f = .$category) %>%
purrr::map(~annotation_custom2(
grob = ggplotGrob(get_inset(.) +
scale_y_continuous(limits=c(0,105), breaks = c(0, 50, 100))),
data = data.frame(category=unique(.$category)),
ymin = -8, ymax=34, xmin=1955, xmax=2015)
)
main_plot + insets
看起来好像没问题了。
3结尾
一天一个小技能。
所以今天你学习了吗?
关注下方公众号,分享更多更好玩的R语言知识。
点个在看,SCI马上发表。